
package models.spider.index;

import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.TypedQuery;

import org.apache.commons.codec.digest.DigestUtils;

import play.db.jpa.JPA;

/**
 * 
 * @author laurent@opprecht.info
 */
@Entity
@Table(name = "spider_index")
public class Entry {

    public static class Finder {

        public TypedQuery<Entry> createQuery(final String sql) {
            TypedQuery<Entry> result = JPA.em().createQuery(sql, Entry.class);
            return result;
        }

        public TypedQuery<Entry> query(final String sql, final Object... parameters) {
            TypedQuery<Entry> result = createQuery(sql);
            for (int i = 0; i < parameters.length; i++) {
                result.setParameter(i + 1, parameters[i]);
            }
            return result;
        }

        public TypedQuery<Entry> query(final String sql) {
            return query(sql, new Object[] {});
        }

        public Entry byUrl(final String url) {
            if (url == null) {
                return null;
            }
            String hash = h(url);

            String sql = "SELECT e FROM Entry e WHERE e.hash = ? AND e.url = ?";
            List<Entry> items = query(sql, hash, url).getResultList();
            for (Entry item : items) {
                return item;
            }
            return null;
        }

        public TypedQuery<Entry> before(final Date date) {
            String sql = "SELECT e FROM Entry e WHERE e.modified < ? ORDER BY modified ASC";
            TypedQuery<Entry> result = query(sql, date);
            return result;
        }

    }

    public static final Finder find             = new Finder();

    @SuppressWarnings("unused")
    private static final long  serialVersionUID = 8372515429762011583L;

    public static String h(final String url) {
        return new String(DigestUtils.md5Hex(url));
    }

    public static Date startOfTime() {
        return new Date(0);

    }

    public static Entry get(final String url) {
        Entry result = null;
        result = find.byUrl(url);
        if (result != null) {
            return result;
        }
        result = new Entry(url);
        return result;
    }

    @Id
    @GeneratedValue
    public Long      id       = null;
    protected String url      = null;
    protected String hash     = null;
    protected Date   created  = null;
    protected Date   modified = null;
    protected int    errors   = 0;

    protected Entry() {
        created = new Date();
        modified = startOfTime();
    }

    protected Entry(final String url) {
        this();
        setUrl(url);
    }

    public Long getId() {
        return id;
    }

    public void setId(final Long value) {
        id = value;
    }

    public String getHash() {
        return hash;
    }

    protected void setHash(final String hash) {
        this.hash = hash;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(final String url) {
        this.hash = h(url);
        this.url = url;
    }

    public int getErrors() {
        return errors;
    }

    public void setErrors(final int value) {
        errors = value;
    }

    public Date getModified() {
        return modified;
    }

    public void setModified(final Date value) {
        modified = value;
    }

    @PrePersist
    @PreUpdate
    void beforeSave() {
        // hash = h(url);
        // mtime = new Date();
    }

}
